package nl.utwente.eemcs.graph;

import java.util.HashMap;

import br.ufscar.dc.graph.Abstraction;

import nl.utwente.eemcs.graph.distribution.DistributionLocation;


/**
 * Abstract node class, with distribution location and a name
 * @author Evert Duipmans
 */
public abstract class Node implements Abstraction {
	/**
	 * Name of the node
	 */
	protected String name;
	
	/**
	 * List with attributes of the node, used for storing relevant information
	 */
	protected HashMap<String, Object> attributes;
	
	/**
	 * Distribution location of the node (onpremise is standard value)
	 */
	protected DistributionLocation location = DistributionLocation.OnPremise;
	
	/**
	 * Boolean indicating if the node is always executed
	 */
	protected boolean executionGuaranteed = true;

	/**
	 * Parent graph of the node
	 */
	protected Graph parentGraph = null;
	
	/**
	 * Get the distribution location of the node
	 * @return Distribution location
	 */
	public DistributionLocation getLocation() {
		return location;
	}

	/**
	 * Set the distribution location
	 * @param location Distribution location
	 */
	public void setLocation(DistributionLocation location) {
		this.location = location;
	}

	/**
	 * Create a node with a name
	 * @param name Name
	 */
	public Node(String name) {
		this.name = name;
		this.attributes = new HashMap<String, Object>();
	}

	/**
	 * Get the name of the current node
	 * @return Name of the node
	 */
	public String getName() {
		return name;
	}

	/**
	 * Set name of the node
	 * @param name Name
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * Add attribute to the attributes list
	 * @param key Name of the attribute
	 * @param value Value of the attribute
	 */
	public void addAttribute(String key, Object value) {
		this.attributes.put(key, value);
	}
	
	/**
	 * Check if the current item has an attribute with a certain name
	 * @param key Name of the element
	 * @return True, if the attribute exists in the attribute list
	 */
	public boolean hasAttribute(String key) {
		return this.attributes.containsKey(key);
	}
	
	/**
	 * Get a value from the attribute list
	 * @param key Name of the attribute
	 * @return Value of the attribute
	 */
	public Object getAttribute(String key) {
		return this.attributes.get(key);
	}
	
	/**
	 * Get the whole attributes list
	 * @return Hash map with attributes
	 */
	public HashMap<String, Object> getAttributes() {
		return this.attributes;
	}
	
	/**
	 * Checks if the execution of the node is guaranteed
	 * @return True, if the node is always executed (thus not in a conditional branch or loopbranch)
	 */
	public boolean isExecutionGuaranteed() {
		return executionGuaranteed;
	}

	/**
	 * Sets if the execution of the node is guaranteed
	 * @param executionGuaranteed
	 */
	public void setExecutionGuaranteed(boolean executionGuaranteed) {
		this.executionGuaranteed = executionGuaranteed;
	}	
	
	/**
	 * Sets the parent graph of the node
	 * @param parentGraph
	 */
	public void setParentGraph(Graph parentGraph) {
	   this.parentGraph = parentGraph;
	}
	
	/**
	 * Gets the parent graph of the node
	 * @param parentGraph
	 */
	public Graph getParentGraph() {
	   return this.parentGraph;
	}
	
	/**
	 * Convert the node to a string
	 */
	@Override
	public String toString() {
		return this.name; 
	}
}